package top.jacktgq.concurrent_utils;

import top.jacktgq.utils.LogUtils;
import top.jacktgq.utils.Sleeper;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @Author CandyWall
 * @Date 2020/11/6--1:14
 * @Description 测试使用倒计时锁
 */
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //demo1();
        //demo2();
        demo3();
    }

    private static void demo1() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2);

        new Thread(() -> {
            LogUtils.log("CountDownLatchDemo-1", "begin...");
            Sleeper.sleep(1);
            latch.countDown();
            LogUtils.log("CountDownLatchDemo-1", "end...");
        }, "t1").start();

        new Thread(() -> {
            LogUtils.log("CountDownLatchDemo-1", "begin...");
            Sleeper.sleep(2);
            latch.countDown();
            LogUtils.log("CountDownLatchDemo-1", "end...");
        }, "t2").start();

        new Thread(() -> {
            LogUtils.log("CountDownLatchDemo-1", "begin...");
            Sleeper.sleep(3);
            latch.countDown();
            LogUtils.log("CountDownLatchDemo", "end...");
        }, "t3").start();

        LogUtils.log("CountDownLatchDemo", "waiting...");
        latch.await();//等待计数器减到0，才会继续向下执行
        LogUtils.log("CountDownLatchDemo", "wait end...");
    }

    private static void demo2() {
        CountDownLatch latch = new CountDownLatch(2);
        ExecutorService threadPool = Executors.newFixedThreadPool(4);
        threadPool.submit(() -> {
           LogUtils.log("CountDownLatchDemo-2", "task 1 begin...");
           Sleeper.sleep(1);
           latch.countDown();
           LogUtils.log("CountDownLatchDemo-2", "task 1 end..." + latch.getCount());
        });
        threadPool.submit(() -> {
           LogUtils.log("CountDownLatchDemo-2", "task 2 begin...");
           Sleeper.sleep(2);
           latch.countDown();
           LogUtils.log("CountDownLatchDemo-2", "task 2 end..." + latch.getCount());
        });
        threadPool.submit(() -> {
           LogUtils.log("CountDownLatchDemo-2", "task 3 begin...");
           Sleeper.sleep(3);
           latch.countDown();
           LogUtils.log("CountDownLatchDemo-2", "task 3 end..." + latch.getCount());
        });
        threadPool.submit(() -> {
           LogUtils.log("CountDownLatchDemo-2", "waiting...");
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
           LogUtils.log("CountDownLatchDemo-2", "wait end...");
        });
    }

    //模拟王者荣耀：所有用户都加载完毕才能进入游戏
    private static void demo3() throws InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        CountDownLatch latch = new CountDownLatch(10);
        Random random = new Random();
        //存储每个用户的进度信息
        String[] progresses = new String[10];
        for (int j = 0; j < 10; j++) {
            int k = j;
            threadPool.submit(() -> {
                for (int i = 0; i <= 100; i++) {
                    progresses[k] = i + "%";
                    Sleeper.sleep(random.nextInt(1000), TimeUnit.MILLISECONDS);
                    System.out.print("\r" + Arrays.toString(progresses));
                }
                latch.countDown();
            });
        }
        latch.await();
        System.out.println();
        System.out.println("所有用户都已经加载完毕，游戏开始");
        threadPool.shutdown();
    }
}
